
#ifndef BIG_FILE_DEMO_HPP
#define BIG_FILE_DEMO_HPP

#include <cstdio>
#include <fstream>
#include <iostream>
#include <cstdint>
#include <algorithm>
#include <limits>
// #include <boost/multiprecision/cpp_int.hpp>

namespace demo {

class big_file_demo final {
private:
  std::filebuf fb;

public:
  big_file_demo(/* args */) {}
  ~big_file_demo() {}
  bool init() {return false;}
  void uninit() {}
  bool open_file(const std::string &file_name) {
    if (!fb.open(file_name, std::ios::binary | std::ios::in | std::ios::out | std::ios::trunc)) {
      std::cout << "Open file " << file_name << " for read failed\n";
      return false;
    }
    return true;
  }
  void close_file() {
    if (fb.is_open()) {
      fb.close();
    }
  }
  void write_byte(const std::string &content) {
    if (fb.is_open()) {
      fb.sputn(content.data(), content.length());
    }
  }

  void read_byte(std::string &content) {
    if (fb.is_open()) {
      char buf[1024] = {0};
      auto size = fb.sgetn(buf, 1024);
      content = std::string(buf, size);
    }
  }

  void set_pos(const int pos) {
    if (fb.is_open()) {
      fb.pubseekpos(pos);
    }
  }

public:
  // 可以采用多次调用的方式进行扩大文件，通过偏移量
  void _change_file_size(const std::streamoff size) {
    if (fb.is_open()) {
      // fb.pubseekpos(size);
      fb.pubseekoff(size, std::ios::seek_dir::cur);
    }
  }
};

} // namespace big_file_demo

void big_file_test() {
  auto ret = std::numeric_limits<std::streampos>::max();
  auto ret2 = std::numeric_limits<long long>::max();
  std::cout << ret << std::endl;
  auto ret6 = sizeof(long long);
  std::cout << ret6 << std::endl;
  using namespace demo;
  demo::big_file_demo demo;
  demo.open_file("/Volumes/data/tmp/test.vx");
  std::uint64_t ret3 = 1024 * 1024 * 1024;
  auto ret4 = 1024 * 1024 * 1024 << 5;
  // mbstate_t mbs = 1024 * 1024 * 1024 << 5;
  demo._change_file_size(1024 * 1024 * 1024 << 5);
  std::string intput("123");
  std::cout << "intput: " << intput << std::endl;
  demo.write_byte(intput);
  demo.set_pos(1024 * 1024 * 1024);
  std::string output;
  demo.read_byte(output);
  std::cout << "output: " << output << std::endl;
}

#endif // BIG_FILE_DEMO_HPP